17

一 前言

1.在typescript上遇到过实例化对象的两种写法:implement和extends。extends很明显就是ES6里面的类继承,那么implement又是做什么的呢?它和extends有什么不同?

2.还有一个问题就是:typescript 有接口的概念,这个接口和类有什么关系吗?

带着以上两个问题我们一起看一下这篇文章。

二 正文

1.ts中interface与class的区别

interface:接口只声明成员方法,不做实现。

class:类声明并实现方法。

也就是说:interface只是定义了这个接口会有什么,但是没有告诉你具体是什么。
例如:

interface Point {
    lng:number;
    lat:number;
    sayPosition():void;
}

Point interface 里面包含数值类型的经纬度和一个sayPosition函数,但是具体内容没有定义,需要你自己在子类中实现。

而class则是完整的实现:

class Point {
    constructor(lng,lat){
        this.lng = lng;
        this.lat = lat;
    }
    sayPosition(){
        console.log('point:',this.lng,this.lat);
    }
}

2.extends 与 implement

(1)extends是继承父类,只要那个类不是声明为final或者那个类定义为abstract的就能继承。

(2)java中不支持多重继承,但是可以用接口来实现,这样就要用到implements,继承只能继承一个类,但implements可以实现多个接口,用逗号分开就行了
比如:

 class A extends B implements C,D,E

在英文中:
implements 就是:实现的意思。
“implement是实现一个接口,要自己实现这个接口的方法”
implements就是实现的意思,顾名思义它实现一个已经定义好的接口中的方法!如:

public interface MyInterface{
    public String MyInterfaceMethod1ToReturnString();
    public void MyIntefaceMethod2();
    ......
    //在这里定义一系列不需要实现的方法,其实现过程"延续到"他的子类中
}

实现接口方法:

public MyImplClass implements MyInterface{
    public String MyInterfaceMethod1ToReturnString(){
         return "My String here!";
    }
    public void MyIntefaceMethod2(){
         //Do something else here!
    }
}

3.ES6中使用Mixin实现“多重继承”

熟悉 JavaScript 的同学应该对 mixin 模式并不陌生。我们说 JavaScript / ES5 的继承模型是基于单一原型链的继承模型,通常情况下,在 JavaScript 实践中完全用原型链来实现继承式的代码复用,是远远不能满足需求的。因此实战中,我们的代码抽象基本上都是采用混合的模式,既有原型继承,也有 mixin 组合。

在 ES6 中,我们可以采用全新的基于类继承的 “mixin” 模式设计更优雅的“语义化”接口,这是因为 ES6 中的 extends 可以继承动态构造的类,这一点和其他的静态声明类的编程语言不同。

const Serializable = Sup => class extends Sup {
  constructor(...args){
    super(...args);
    if(typeof this.constructor.stringify !== "function"){
      throw new ReferenceError("Please define stringify method to the Class!");
    }
    if(typeof this.constructor.parse !== "function"){
      throw new ReferenceError("Please define parse method to the Class!");
    }
  }
  toString(){
    return this.constructor.stringify(this);
  }
}

class Person {
  constructor(name, age, gender){
    Object.assign(this, {name, age, gender});
  }
}

class Employee extends Serializable(Person){
  constructor(name, age, gender, level, salary){
    super(name, age, gender);
    this.level = level;
    this.salary = salary;
  }
  static stringify(employee){
    let {name, age, gender, level, salary} = employee;
    return JSON.stringify({name, age, gender, level, salary});
  }
  static parse(str){
    let {name, age, gender, level, salary} = JSON.parse(str);
    return new Employee(name, age, gender, level, salary);
  }
}

let employee = new Employee("jane",25,"f",1,1000);
let employee2 = Employee.parse(employee+""); //通过序列化反序列化复制对象

console.log(employee2, 
  employee2 instanceof Employee,  //true 
  employee2 instanceof Person,  //true
  employee == employee2);   //false

在上面的代码里,我们改变了 Serializable,让它成为一个动态返回类型的函数,然后我们通过 class Employ extends Serializable(Person) 来实现可序列化,在这里我们没有可序列化 Person 本身,而将 Serializable 在语义上变成一种修饰,即 Employee 是一种可序列化的 Person。

三 后记

参考链接:
Classes
类的装饰器:ES6 中优雅的 mixin 式继承


specialcoder
2.2k 声望170 粉丝

前端 设计 摄影 文学